/**
 * Copyright (c) 2019 Coder League
 * All rights reserved.
 *
 * File：QrCodeUtils.java
 * History:
 *         2019年8月21日: Initially created, CJH.
 */
package club.coderleague.ilsp.util;

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import org.apache.commons.lang3.StringUtils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * 二维码工具
 *
 * @author CJH
 */
public class QrCodeUtils {
	
	private static final String CHARSET = "utf-8";
	public static final String FORMAT = "JPG";
	// 二维码尺寸
	private static final int QRCODE_SIZE = 300;
	// LOGO宽度
	private static final int LOGO_WIDTH = 60;
	// LOGO高度
	private static final int LOGO_HEIGHT = 60;
	
	/**
	 * 生成二维码
	 * 
	 * @author CJH 2019年8月21日
	 * @param content 二维码内容
	 * @return 二维码图片数据
	 */
	public static BufferedImage createImage(String content) {
		return QrCodeUtils.createImage(content, null);
	}

	/**
	 * 生成二维码
	 *
	 * @param content 二维码内容
	 * @param logopath LOGO图片地址
	 * @return 二维码图片数据
	 */
	public static BufferedImage createImage(String content, String logopath) {
		BufferedImage qrcodeimage = null;
		try {
			Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
			hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
			hints.put(EncodeHintType.MARGIN, 1);
			BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
			int qrcodewidth = bitMatrix.getWidth();
			int qrcodeheight = bitMatrix.getHeight();
			qrcodeimage = new BufferedImage(qrcodewidth, qrcodeheight, BufferedImage.TYPE_INT_RGB);
			for (int x = 0; x < qrcodewidth; x++) {
				for (int y = 0; y < qrcodeheight; y++) {
					qrcodeimage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
				}
			}
			if (StringUtils.isBlank(logopath)) {
				return qrcodeimage;
			}
			// 插入图片
			QrCodeUtils.insertImage(qrcodeimage, logopath);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return qrcodeimage;
	}

	/**
	 * 插入LOGO图片
	 * 
	 * @author CJH 2019年8月21日
	 * @param qrcodeimage 二维码图片
	 * @param logopath LOGO图片地址
	 */
	public static void insertImage(BufferedImage qrcodeimage, String logopath) {
        InputStream logoinputstream = null;
        try {
            logoinputstream = new FileInputStream(new File(logopath));
            Image logoimage = ImageIO.read(logoinputstream);
            int logoimagewidth = logoimage.getWidth(null);
            int logoimageheight = logoimage.getHeight(null);
            if (logoimagewidth > LOGO_WIDTH) {
                logoimagewidth = LOGO_WIDTH;
            }
            if (logoimageheight > LOGO_HEIGHT) {
                logoimageheight = LOGO_HEIGHT;
            }
            Image scaledimage = logoimage.getScaledInstance(logoimagewidth, logoimageheight, Image.SCALE_SMOOTH);
            BufferedImage scaledimagebuffered = new BufferedImage(logoimagewidth, logoimageheight, BufferedImage.TYPE_INT_RGB);
            Graphics scaledimagegraphics = scaledimagebuffered.getGraphics();
            scaledimagegraphics.drawImage(scaledimage, 0, 0, null);
            scaledimagegraphics.dispose();
            logoimage = scaledimage;
            
            Graphics2D graph = qrcodeimage.createGraphics();
            int x = (QRCODE_SIZE - logoimagewidth) / 2;
            int y = (QRCODE_SIZE - logoimageheight) / 2;
            graph.drawImage(logoimage, x, y, logoimagewidth, logoimageheight, null);
            Shape shape = new RoundRectangle2D.Float(x, y, logoimagewidth, logoimagewidth, 6, 6);
            graph.setStroke(new BasicStroke(3f));
            graph.draw(shape);
            graph.dispose();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (logoinputstream != null) {
				try {
					logoinputstream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
            }
        }
    }
}